﻿#include "liblog.h"
#include "CLogManager.hpp"

#if defined(WIN32)
#include <io.h>
#include <direct.h>
#elif defined(__linux__)
#include <stdarg.h>
#include <sys/stat.h>
#endif

#if defined(WIN32)
#define ACCESS _access
#define MKDIR(a) _mkdir((a))
#elif defined(__linux__)
#define ACCESS access
#define MKDIR(a) mkdir((a),0755)
#endif

inline const char* CreatePath(char* Logdir)
{
	int r = -1;
	char* p = Logdir;
	if(*p == '\\' || *p == '/')
	{
		p++;
	}
	
	while(*p != '\0')
	{
		if(*p == '\\' || *p == '/')
		{
			*p = '\0';
			r = ACCESS(Logdir,0);
			if (r != 0)
			{
				r = MKDIR(Logdir);
				if (r != 0)
				{
					return NULL;
				}
			}

			*p = '/';
		}
		p++;
	}

	if (*(p-1) != '/')
	{
		*p = '/';
		*(++p) = '\0';

		r = ACCESS(Logdir,0);
		if (r != 0)
		{
			r = MKDIR(Logdir);
			if (r != 0)
			{
				return NULL;
			}
		}
	}

	return Logdir;
}

LIBLOG_API bool LibLog_SetDir(const char* dir)
{
	if (dir != NULL)
	{
		CLogManager& logManager  = CLogManager::Instance();
		CAutoLock _lock(logManager.lock);

		char tmp[270] = {'\0'};
		strncpy(tmp,dir,270);

		const char* logdir = CreatePath(tmp);
		if (NULL != logdir)
		{
			logManager.logdir = logdir;
			return true;
		}
	}
	
	return false;
}

LIBLOG_API void LibLog_SetLogCallback(LibLogCallback fCallback,void* param)
{
	CLogManager& logManager  = CLogManager::Instance();
	CAutoLock _lock(logManager.lock);
	logManager.fCallback = fCallback;
	logManager.param = param;
}

LIBLOG_API const char* LibLog_GetDir()
{
	CLogManager& logManager  = CLogManager::Instance();
	CAutoLock _lock(logManager.lock);
	return logManager.logdir.c_str();
}

//设置每n条日志fflush一次到文件，默认50条
LIBLOG_API void LibLog_SetFlushLines(unsigned int nLines)
{
	CLogManager& logManager  = CLogManager::Instance();
	CAutoLock _lock(logManager.lock);
	logManager.flushlines = nLines > 1 ? nLines : 1;
}

LIBLOG_API unsigned int LibLog_GetFlushLines()
{
	CLogManager& logManager  = CLogManager::Instance();
	CAutoLock _lock(logManager.lock);
	return logManager.flushlines;
}

//立即写入文件
LIBLOG_API void LibLog_FlushFile()
{
	CLogManager& logManager  = CLogManager::Instance();
	logManager.FlushLog();
}

LIBLOG_API void LibLog_SetFileTimeInterval(unsigned int nHours)
{
	CLogManager& logManager  = CLogManager::Instance();
	CAutoLock _lock(logManager.lock);
	logManager.timeinterval = nHours > 1 ? nHours : 1;
}

LIBLOG_API unsigned int LibLog_GetFileTimeInterval()
{
	CLogManager& logManager  = CLogManager::Instance();
	CAutoLock _lock(logManager.lock);
	return logManager.timeinterval;
}

// 是否打印到屏幕，默认true
LIBLOG_API void LibLog_IsPrintScreen(bool bScreen)
{
	CLogManager& logManager  = CLogManager::Instance();
	CAutoLock _lock(logManager.lock);
	logManager.printscreen = bScreen;
}

LIBLOG_API bool LibLog_GetPrintScreen(void)
{
	CLogManager& logManager  = CLogManager::Instance();
	CAutoLock _lock(logManager.lock);
	return logManager.printscreen;
}

// 设置日志文件保存的有效期，默认7天
LIBLOG_API void LibLog_SetLogExpireTime(unsigned int nDays)
{
	CLogManager& logManager  = CLogManager::Instance();
	CAutoLock _lock(logManager.lock);
	logManager.expiredays = nDays > 1 ? nDays : 1;
}

LIBLOG_API unsigned int LibLog_GetLogExpireTime()
{
	CLogManager& logManager  = CLogManager::Instance();
	CAutoLock _lock(logManager.lock);
	return logManager.expiredays;
}

//设置日志打印级别
LIBLOG_API void LibLog_SetPrintLevel(int printLevel)
{
	CLogManager& logManager  = CLogManager::Instance();
	CAutoLock _lock(logManager.lock);
	logManager.printLevel = printLevel > -1 ? printLevel : -1;;
}

LIBLOG_API int LibLog_GetPrintLevel()
{
	CLogManager& logManager  = CLogManager::Instance();
	CAutoLock _lock(logManager.lock);
	return logManager.printLevel;
}

//打印日志
LIBLOG_API void LibLog_Print(int LogLevel, const char* format, ...)
{
	va_list argList;
	va_start(argList, format);
	::LibLog_PrintEx(LogLevel, format, argList);
	va_end(argList);
}

LIBLOG_API void LibLog_PrintEx(int LogLevel,const char* format,va_list argList)
{
	CLogManager& logManager  = CLogManager::Instance();
	
	int len = CaleFormatLen(format, argList);
	assert(len>=0);
	
	char* pbuf = new char[len+1];
	len = vsnprintf(pbuf,len+1,format, argList);
	assert(len>=0);

	logManager.WriteLog(NULL,LogLevel,pbuf,len);

	delete []pbuf;
}

LIBLOG_API void LibLog_PrintLog(const char* prefix,int LogLevel,const char* format, ...)
{
	if (prefix == NULL)
	{
		return;
	}

	va_list argList;
	va_start(argList, format);
	::LibLog_PrintLogEx(prefix, LogLevel,format, argList);
	va_end(argList);
}

LIBLOG_API void LibLog_PrintLogEx(const char* prefix,int LogLevel,const char* format,va_list argList)
{
	if (prefix == NULL)
	{
		return;
	}

	CLogManager& logManager  = CLogManager::Instance();

	int len = CaleFormatLen(format, argList);
	assert(len>=0);

	char* pbuf = new char[len+1];
	len = vsnprintf(pbuf,len+1,format, argList);
	assert(len>=0);

	logManager.WriteLog(prefix,LogLevel,pbuf,len);

	delete []pbuf;
}
